一覧に戻る

AWS AmplifyのHostingに待望のIAM Compute Rolesが実装されたので試す

#AWS#IAM#フロントエンド#amplify#SvelteKit

TL;DR

  • Amplify HostingでSSRする際に不足していた「実行ロール」機能が実装された。これでSSR環境下で安全にAWSリソースを利用できる
  • 今までは安全にAWSリソースを制御するには、Amplify Backendか、IAMユーザーのクレデンシャルを持たせるかしか方法がなかったが、これが解決する(AWSのほかのコンピューティングと同じように使える)

Amplify Hostingの実行環境にIAMロールを設定出来るようになった

https://aws.amazon.com/jp/blogs/mobile/iam-compute-roles-for-server-side-rendering-with-aws-amplify-hosting/

Amplify Hostingでは最近はServer-side Rendering(SSR)がサポートされていて、Node.js上でフロントエンドアプリケーションを実行してくれるようになっています。ただしこれまで、そのNode.js実行環境にIAMロールを設定することが出来ませんでした。このアップデートでIAMロールを設定出来るようになり、Node.jsから安全にAWSリソースを操作出来るようになります。

本記事では、SvelteKitを利用して、IAMロールに基づいたAWSリソースの制御をテストします。

検証

S3バケットの作成

バケットを作成してファイルを置いておく。ここではamplify-role-testというバケットにmock.jsonというファイルを配置。

{
	"message": "hello amplify"
}

IAMポリシーの作成

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::amplify-role-test/*"
        }
    ]
}

IAMロールの作成

「カスタム信頼ポリシー」を選択して以下のポリシーを記述

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "amplify.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

SvelteKitアプリケーションの作成

SvelteKitはAmplifyで動作します。詳しくは以下の記事を参照してください。

https://qiita.com/Kanahiro/items/dd4afc0d0871b97d4f33

npx sv create svelte-amplify-ssr-role
cd svelte-amplify-ssr-role
pnpm add -D @aws-sdk/client-s3 amplify-adapter
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { json } from '@sveltejs/kit';

const s3 = new S3Client({
	region: 'ap-northeast-1',
});

export async function GET() {
	// getobject
	const params = {
		Bucket: 'amplify-role-test',
		Key: 'mock.json',
	};
	const command = new GetObjectCommand(params);
	const response = await s3.send(command);
	const jsonStr = await response.Body.transformToString();
	const _json = JSON.parse(jsonStr);
	return json(_json);
}

import type { PageServerLoad } from './$types';
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
const s3 = new S3Client({
	region: 'ap-northeast-1',
});

export const load: PageServerLoad = async ({}) => {
	// getobject
	const params = {
		Bucket: 'amplify-role-test',
		Key: 'mock.json',
	};
	const command = new GetObjectCommand(params);
	const response = await s3.send(command);
	const jsonStr = await response.Body.transformToString();
	const _json = JSON.parse(jsonStr) as { message: string };
	return {
		mock: _json,
	};
};
<script lang="ts">
	let { data } = $props();

	async function fetchS3() {
		const response = await fetch('/api/mock');
		const json = await response.json();
		alert(JSON.stringify(json, null, 2));
	}
</script>

<!-- SSR -->
<p>mock.json:</p>
<pre>{JSON.stringify(data, null, 2)}</pre>

<!-- Fetch API via API Routes -->
<button onclick={fetchS3}>Fetch S3</button>
import adapter from 'amplify-adapter';
// 以下略

コードはGitHubにあげておきましょう。上記のコードは:

  1. /api/mockに対するGETリクエストの実装
  2. /で返却するページの実装

がそれぞれ含まれています。1はREST-APIのことで、Fetch APIで動作を検証しています。2はSSRのことで、/にアクセスした際に返却されるHTMLの内容にS3の内容が含まれています。

https://github.com/MIERUNE/svelte-amplify-ssr-role

Amplifyアプリケーションの作成

version: 1
frontend:
    phases:
        preBuild:
            commands:
                - 'npm install -g pnpm'
                - 'pnpm install'
        build:
            commands:
                - 'pnpm build'
                - 'cd build/compute/default/'
                - 'npm i --production'
    artifacts:
        baseDirectory: build
        files:
            - '**/*'
    cache:
        paths:
            - 'node_modules/**/*'

コンピューティングロールの設定

「アプリケーションの設定」に「IAMロール」が追加されているので、「コンピューティングロール」に先ほど作成したIAMロールを設定します。ブランチごとに区別することも出来るようですね。

動作検証

デプロイされたアプリケーションにアクセスします。

S3から取得したJSONでSSRされている

API Routesに対するFetch APIの結果。S3にあるファイルを取得できている。

コンピューティングロールの設定を解除してみる

再度デプロイして(重要、デプロイ時にIAMロールが決定されるもよう)、アプリケーションにアクセスする

エラーが発生するようになる、ログを確認する

クレデンシャルが読めてなさそうなので、期待どおりの挙動

終わりに

全俺が待ってたアップデートゆえ取り急ぎ検証回しました Amplify + SSRについては以下のようなトークを持ったこともありました

https://docs.google.com/presentation/d/15fUcmbF02-K_crddDpyMFiBpVrFbpH22_jKUaOcJJs8/edit?usp=sharing

そこでも「実行ロール」が利用できないことには言及していました 今回のアップデートにより、Amplify Hostingの活用の幅がより広がるものと期待しています